/// Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.ObjectModel;

namespace Microsoft.VSPowerToys.PackInstaller
{
    /// <summary>
    /// Shows a tag cloud of list of tags provided to the control and allows
    /// user to select one of the tags listed.
    /// </summary>
    public class SortListView : ListView
    {
        private ColumnHeader columnName;
        private SortOrder sortOrder = SortOrder.None;
        private bool selectionChanged = false;
        private bool setHeight = false;

#if TEST
        public string ImageFileName
        {
            get
            {
                return (sortOrder == SortOrder.Ascending) ?
                    "Up_Arrow" : "Down_Arrow";
            }
        }

        private MouseEventArgs mouseEventArgs;
        public string  TriggerMouseEvent
        {
            set 
            {
                foreach (ListViewItem listItem in this.Items)
                {
                    if (listItem.Text == value)
                    {
                        listItem.Selected = true;
                        mouseEventArgs = new MouseEventArgs(MouseButtons.Left, 1, listItem.Position.X, listItem.Position.Y, 0);
                        this.OnMouseClick(mouseEventArgs);
                    }
                }
            }
        }

#endif

        /// <summary>
        /// Raised when user changes the sort ordering
        /// </summary>
        public event EventHandler SortOrderChanged;

        /// <summary>
        /// Gets the selected sort field (null if no field is selected)
        /// </summary>
        public string SortFieldName
        {
            get
            {
                if (this.SelectedItems.Count > 0)
                {
                    return this.SelectedItems[0].Text;
                }
                else
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// Gets the object assigned to the selected sort field
        /// </summary>
        public object SortFieldObject
        {
            get
            {
                if (this.SelectedItems.Count > 0)
                {
                    return this.SelectedItems[0].Tag;
                }
                else
                {
                    return null;
                }
            }
            set
            {
                if (value != null)
                {
                    foreach (ListViewItem item in this.Items)
                    {
                        item.Selected = (value.Equals(item.Tag));
                    }
                    this.Refresh();
                }
            }
        }

        /// <summary>
        /// Gets the sort order selected by the user
        /// </summary>
        public SortOrder SortOrder
        {
            get { return this.sortOrder; }
            set
            {
                this.sortOrder = value;
                this.Refresh();
            }
        }

        /// <summary>
        /// Creates a new sort list view object
        /// </summary>
        public SortListView()
            : base()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Updates the list view
        /// (Calling this method clears all the items)
        /// </summary>
        /// <param name="sortFields">Dictionary of field names and field objects</param>
        public void UpdateList(Dictionary<string, object> sortFields)
        {
            this.BeginUpdate();
            this.Items.Clear();
            setHeight = true;
            foreach (KeyValuePair<string, object> pair in sortFields)
            {
                ListViewItem item = new ListViewItem(pair.Key);
                item.Tag = pair.Value;
                item.ToolTipText = pair.Key;
                this.Items.Add(item);
            }
            this.EndUpdate();
        }

        /// <summary>
        /// Initializes the layout of the control
        /// </summary>
        protected override void InitLayout()
        {
            base.InitLayout();
            this.View = View.Details;
            this.MultiSelect = false;
            this.GridLines = false;
            this.BorderStyle = BorderStyle.None;
            this.OwnerDraw = true;
            this.HeaderStyle = ColumnHeaderStyle.None;
        }

        protected override void OnDrawItem(DrawListViewItemEventArgs e)
        {
            e.DrawDefault = false;
            if (this.setHeight)
            {
                this.setHeight = false;
                this.Height = (this.Margin.Bottom + this.Margin.Top) + e.Bounds.Height * this.Items.Count;
            }
            base.OnDrawItem(e);
        }

        protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
        {
            e.DrawDefault = false;
            e.DrawBackground();
            if (e.Item.Selected && e.Header.Text.Equals("Name") && sortOrder != SortOrder.None)
            {
                Image bullet = (sortOrder == SortOrder.Ascending) ?
                    Properties.Resources.Up_Arrow : Properties.Resources.Down_Arrow;
                e.Graphics.DrawImage(bullet,
                    new Rectangle(e.Bounds.X, e.Bounds.Y +((e.Bounds.Height - 9)/2), 9, 9));
            }

            if (this.Enabled)
            {
                this.ForeColor = SystemColors.WindowText;
            }
            else
            {
                this.ForeColor = SystemColors.GrayText;
            }

            e.DrawText(TextFormatFlags.VerticalCenter);

            base.OnDrawSubItem(e);
        }

        protected override void OnItemSelectionChanged(ListViewItemSelectionChangedEventArgs e)
        {
            if (this.SelectedItems.Count > 0)
            {
                this.selectionChanged = true;
            }
            base.OnItemSelectionChanged(e);
        }

        /// <summary>
        /// Handles the mouse click event. If user clicks on an item that is already selected,
        /// this method reverses the sort ordering
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ListViewItem item = this.GetItemAt(e.X, e.Y);

                if (item != null && this.SelectedItems.Count > 0 && this.SelectedItems[0] == item)
                {
                    if (this.selectionChanged)
                    {
                        this.sortOrder = SortOrder.Ascending;
                        this.selectionChanged = false;
                    }
                    else
                    {
                        this.sortOrder = (this.sortOrder == SortOrder.Ascending) ? SortOrder.Descending : SortOrder.Ascending;
                    }
                    this.Refresh();
                    if (this.SortOrderChanged != null)
                    {
                        this.SortOrderChanged(this, null);
                    }
                }
            }

            base.OnMouseClick(e);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.columnName.Width = this.Width;
        }

        /// <summary>
        /// Changes the mouse cursor to Hand cursor if user is on the first column of an item
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            ListViewItem item = this.GetItemAt(e.X, e.Y);
            ListViewItem.ListViewSubItem subItem = item != null ? item.GetSubItemAt(e.X, e.Y) : null;
            if (subItem != null && item.SubItems[0] == subItem)
            {
                this.Cursor = Cursors.Hand;
            }
            else
            {
                this.Cursor = null;
            }
            base.OnMouseMove(e);
        }

        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SortListView));
            this.columnName = new System.Windows.Forms.ColumnHeader();
            this.SuspendLayout();
            // 
            // columnName
            // 
            resources.ApplyResources(this.columnName, "columnName");
            // 
            // SortListView
            // 
            this.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnName});
            this.MultiSelect = false;
            this.Scrollable = false;
            this.ShowItemToolTips = true;
            this.ResumeLayout(false);

        }
        
    }
}
